package com.hiof.activities;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.hiof.Configuration;
import com.hiof.R;
import com.hiof.beans.RouteInfo;
import com.hiof.beans.TypeOfRouteStatus;
import com.hiof.beans.UserInfo;
import com.hiof.customviews.CustomRaceRouteArrayAdapter;
import com.hiof.menus.CommandItem;
import com.hiof.menus.NavigationMenu;
import com.hiof.overlays.MapPointsManager;
import com.hiof.servercommunication.RestFulServiceManager;
import com.hiof.servercommunication.exception.NetworkException;
import com.hiof.servercommunication.exception.ServerException;
import com.hiof.servercommunication.receive.beans.RouteInfoCollection;
import com.hiof.servercommunication.status.StartRouteStatus;
import com.hiof.settings.SettingManager;
import com.hiof.settings.user.TypeOfAttendant;
import com.hiof.settings.user.UserConfiguration;
import com.hiof.utility.Utility;
import com.hiof.voiceguide.VoiceType;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: manish
 * Date: 3/24/12
 * Time: 9:00 AM
 * To change this template use File | Settings | File Templates.
 */
public class RaceListActivity extends ListActivity implements Runnable {

    List<RouteInfo> routes = new ArrayList<RouteInfo>();
    ProgressDialog fetchingRoutesProgressDialog;
    ProgressDialog fetchingUserInfoProgressDialog;
    ProgressDialog fetchingMapPointsProgressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Configuration.getInstance().setCurrentContext(this);

        if (routes.size() > 0)
            routes.clear();

        fetchingRoutesProgressDialog = Utility.getProgressBar(getResources().getString(R.string.progress_bar_fetching_route_title), this);
        fetchingRoutesProgressDialog.show();
        Thread thread = new Thread(this);
        thread.start();

        if (routes != null && routes.size() > 0) {

        }
    }

    @Override
    public void run() {
        RouteInfoCollection routeInfoPacket;
        try {
            routeInfoPacket = RestFulServiceManager.getInstance().getRouteDetailsForAthlete(SettingManager.getInstance().getUsername());
            routes = routeInfoPacket.getRouteInfos();
        } catch (NetworkException e) {
            routes.clear();
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ServerException e) {
            routes.clear();
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        Bundle bundle = new Bundle();
        if (routes.size() > 0) {
            bundle.putString("message", "route fetched");
        } else {
            bundle.putString("message", "No route info");
        }

        Message msg = new Message();
        msg.setData(bundle);
        routeFetchHandler.sendMessage(msg);
    }


    private void fetchUserInfo(RouteInfo route) throws ServerException, NetworkException {
        Message msg = new Message();
        Bundle bundle = new Bundle();
        if (route.getStatus() == TypeOfRouteStatus.ONGOING) {
            StartRouteStatus startRouteStatus = RestFulServiceManager.getInstance().startRoute(route.getRouteId());
            if (startRouteStatus == StartRouteStatus.OK) {
                UserInfo uInfo = RestFulServiceManager.getInstance().fetchUserInfo(SettingManager.getInstance().getUsername(), route.getRouteId());
                initializeUserInfo(uInfo, route.getRouteId());
            }
            bundle.putString("message", "Finish fetching");
        }
        msg.setData(bundle);
        userInfoFetchHandler.sendMessage(msg);
    }

    private void initializeUserInfo(UserInfo uInfo, int routeId) {
        Utility.debug(this.getClass().toString(), "setting user info");
        UserConfiguration.getInstance().setUserId(uInfo.getUserId());
        UserConfiguration.getInstance().setUserName(uInfo.getUsername());
        UserConfiguration.getInstance().setAttendantId(uInfo.getAttendantId());
        UserConfiguration.getInstance().setTypeOfAttendant(uInfo.getTypeOfAttendant());
        UserConfiguration.getInstance().setAttendantCode(uInfo.getAttendantCode());
        UserConfiguration.getInstance().setFullName(uInfo.getFullname());
        ArrayList<UserInfo> teammates = (ArrayList) uInfo.getTeamMembers();
        UserConfiguration.getInstance().setTeammates(teammates);
        UserConfiguration.getInstance().setRouteId(routeId);
        UserConfiguration.getInstance().setProfilePicture(uInfo.getProfilePicture());
        UserConfiguration.getInstance().saveInstanceToDatabase();
        Utility.debug(this.getClass().toString(), "setting user info finished");
    }

    private Handler routeFetchHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            fetchingRoutesProgressDialog.dismiss();
            if (msg.getData().get("message").equals("route fetched")) {
                setListAdapter(new CustomRaceRouteArrayAdapter(RaceListActivity.this, R.layout.route_list, routes));
                ListView lv = getListView();
                lv.setTextFilterEnabled(true);
                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    public void onItemClick(AdapterView<?> parent, View view,
                                            int position, long id) {
                        RouteInfo route = (RouteInfo) parent.getAdapter().getItem(position);
                        if (route.getStatus() == TypeOfRouteStatus.ONGOING) {
                            fetchingUserInfoProgressDialog = Utility.getProgressBar(getResources().getString(R.string.progress_bar_fetch_user_info_title), RaceListActivity.this);
                            fetchingUserInfoProgressDialog.show();
                            UserInfoFetcherThread userInfoThread = new UserInfoFetcherThread(route);
                            Thread uInfoThread = new Thread(userInfoThread);
                            uInfoThread.start();
                        }
                    }
                });
            } else {
                Toast.makeText(getApplicationContext(), msg.getData().get("message").toString(),
                        Toast.LENGTH_SHORT).show();
            }
        }
    };

    private Handler userInfoFetchHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            fetchingUserInfoProgressDialog.dismiss();
//            Intent intent = new Intent();
            if (msg.getData().get("message").equals("Finish fetching")) {
                setUpMenuCommandForTeammate();
                fetchingMapPointsProgressDialog = Utility.getProgressBar(getResources().getString(R.string.progress_bar_fetch_route_points), RaceListActivity.this);
                fetchingMapPointsProgressDialog.show();
            }
        }
    };

    private Handler mapParsingFinishHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            fetchingMapPointsProgressDialog.dismiss();
            Intent intent = new Intent();
            if (msg.getData().get("message").equals("Finish parsing")) {
                if (UserConfiguration.getInstance().getTypeOfAttendant() == TypeOfAttendant.ATHLETE) {
                    intent.setClass(RaceListActivity.this, MainActivityAthlete.class);
                } else if (UserConfiguration.getInstance().getTypeOfAttendant() == TypeOfAttendant.SUPPORT) {
                    intent.setClass(RaceListActivity.this, MainActivitySupport.class);
                }
                startActivity(intent);
            }
            finish();
        }
    };

    private Handler exceptionHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            fetchingUserInfoProgressDialog.dismiss();
            Toast.makeText(RaceListActivity.this, String.valueOf(msg.getData().get("message")), Toast.LENGTH_SHORT).show();
        }
    };

    private void setUpMenuCommandForTeammate() {
        ArrayList<UserInfo> teammates = UserConfiguration.getInstance().getTeammates();
        if (teammates.size() == 1) {
            CommandItem commandItem = new CommandItem(VoiceType.TEXT_TO_SPEECH, R.string.call_support);
            NavigationMenu.getInstance().addMoreCommand(commandItem);
        } else if (teammates.size() == 2) {
            try {
                CommandItem commandItem = new CommandItem(VoiceType.TEXT_TO_SPEECH, R.string.call_first_support);
                NavigationMenu.getInstance().addMoreCommand(commandItem);
                CommandItem secondCommandItem = new CommandItem(VoiceType.TEXT_TO_SPEECH, R.string.call_second_support);
                NavigationMenu.getInstance().addMoreCommand(secondCommandItem);
            } catch (Exception e) {
                Utility.error(this.getClass().toString(), e.getMessage());
            }
        }
    }

    private class UserInfoFetcherThread implements Runnable {
        @Override
        public void run() {
            Utility.debug(this.getClass().toString(), "running thread to getuserinfo");

            try {
                fetchUserInfo(route);
                parseRoutePoints(route.getRouteId());
            } catch (ServerException e) {
                Utility.error(this.getClass().toString(), "Error caught:" + e.getErrorMessage());
                handleError(e.getMessage());
            } catch (NetworkException e) {
                Utility.error(this.getClass().toString(), "Error caught:" + e.getErrorMessage());
                handleError(e.getErrorMessage());
            }
        }

        RouteInfo route;

        public UserInfoFetcherThread(RouteInfo route) {
            this.route = route;
        }

        /**
         * parse the selected route points and set them to be able to draw routes
         *
         * @param routeId
         */
        private void parseRoutePoints(int routeId) {
            Message msg = new Message();
            Bundle bundle = new Bundle();
            MapPointsManager mapPointsManager = MapPointsManager.getInstane();
            mapPointsManager.parseMap(routeId);
            bundle.putString("message", "Finish parsing");
            msg.setData(bundle);
            mapParsingFinishHandler.sendMessage(msg);
        }
    }


    private void handleError(String message) {
        Message msg = new Message();
        Bundle bundle = new Bundle();
        bundle.putString("message", message);
        msg.setData(bundle);
        exceptionHandler.sendMessage(msg);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //finish();
    }
}
